package com.coocaa.x.framework.utils;

import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.Settings;
import android.util.Log;

import com.coocaa.x.framework.app.CoocaaApplication;
import com.coocaa.x.framework.data.InstallBackData;
import com.coocaa.x.service.litepm.data.AppInfo;
import com.skyworth.framework.skysdk.android.SdCardChecker;
import com.skyworth.logsdk.appstore.LogAPIForAppStore;

import java.io.File;
import java.io.IOException;
import java.util.List;

public class PMUtils {

    //应用转移方向
    public enum PackageMoveLocation {
        EXTERNAL_MEDIA, INTERNAL_MEMORY
    }

    //应用安装状态
    public static final int INSTALL_STATE_NO_INSTALL = 0;
    public static final int INSTALL_STATE_INSTALLING = 1;
    public static final int INSTALL_STATE_INSTALLED = 2;

    public static final int INSTALL_LOCATION_UNSPECIFIED = -1;
    public static final int INSTALL_LOCATION_AUTO = 0;
    public static final int INSTALL_LOCATION_INTERNAL_ONLY = 1;
    public static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2;



    public static InstallBackData installAPP(String apkfile, boolean silent, boolean SP){
        LogUtils.d("install", "installAPP silent:" + silent +" SP:"+SP);
        if (!new File(apkfile).exists()) {
            InstallBackData data = new InstallBackData();
            data.setData(1,new AppInfo(),"apkFile is not exit");
            return data;
        }
        if(silent)
            return silentInstallApp(apkfile);
        else
        if(SP)
            return unSilentInstallApp(apkfile,true);
        else
            return unSilentInstallApp(apkfile,false);
    }

    private static InstallBackData silentInstallApp(String apkfile)
    {
//        boolean isInstallSuccess = false;
        InstallBackData data = new InstallBackData();
        try {
            LogUtils.d("silent_install", " chmod 777 " + apkfile);
            Runtime.getRuntime().exec("chmod 777 " + apkfile);
        } catch (Exception e) {
            e.printStackTrace();
        }
        AppInfo appinfo = getAPKInfo(apkfile);
        if (appinfo == null) {
//            if (mInstallListener != null) {
//                mInstallListener.onInstallStart(apkfile, null, params);
//                mInstallListener.onInstallEnd(apkfile, null, PM_ERROR,
//                        "INSTALL_FAILED_INVALID_APK", params);
            LogAPIForAppStore.reportError("INSTALL_FAILED_INVALID_APK");
//            }
//            isInstallSuccess = false;
            data.setData(1,null,"apkfile  has no appinfo!!");
        } else {
            int preferlocation = getInstallLocation(apkfile);
            LogUtils.d("install", "preferlocation:" + preferlocation);
            switch (preferlocation) {
                case INSTALL_LOCATION_AUTO:
//                        if (SdCardChecker.isSDCardAvaiable()) {
//                            String arg = " -s ";
//                            if (needInstallSystem(apkfile)) {
//                                arg = "";
//                            }
//                            StringBuilder command = new StringBuilder().append("pm install -r " + arg).append(
//                                    apkfile);
//                            LogUtils.d("slient_install", "INSTALL_LOCATION_AUTO silent install  cmd:" + command);
//                            CommandResult commandResult = ShellUtils
//                                    .execCommand(command.toString(), true, true);
//                            if (commandResult.successMsg != null
//                                    && (commandResult.successMsg.contains("Success") || commandResult.successMsg
//                                    .contains("success"))) {
//                                if (mInstallListener != null)
//                                    mInstallListener.onInstallEnd(apkfile, appinfo, PM_SUCCESSS,
//                                            String.valueOf("Success"), params);
//                                LogAPIForAppStore
//                                        .appStatusNew(-1, appinfo.pkgName, appinfo.appName, "安装成功", "");
//                                break;
//                            }
//                            if (arg.equals("")) {
//                                if (mInstallListener != null) {
//                                    LogUtils.d("slient_install", "arg is   INSTALL_LOCATION_AUTO Silent Install failed  for:" + commandResult.errorMsg);
//                                    mInstallListener.onInstallEnd(apkfile, appinfo, PM_ERROR,
//                                            commandResult.errorMsg, params);
//                                }
//                                break;
//                            }
//                        }
//                        StringBuilder command0 = new StringBuilder().append("pm install -r ").append(
//                                apkfile);
//                        LogUtils.d("slient_install", "INSTALL_LOCATION_AUTO silent install  cmd:" + command0);
//                        CommandResult commandResult0 = ShellUtils
//                                .execCommand(command0.toString(), true, true);
//                        if (commandResult0.successMsg != null
//                                && (commandResult0.successMsg.contains("Success") || commandResult0.successMsg
//                                .contains("success"))) {
//                            if (mInstallListener != null)
//                                mInstallListener.onInstallEnd(apkfile, appinfo, PM_SUCCESSS,
//                                        String.valueOf("Success"), params);
//                            LogAPIForAppStore
//                                    .appStatusNew(-1, appinfo.pkgName, appinfo.appName, "安装成功", "");
//                        } else {
//                            if (mInstallListener != null) {
//                                LogUtils.d("slient_install", "INSTALL_LOCATION_AUTO Silent Install failed  for:" + commandResult0.errorMsg);
//                                mInstallListener.onInstallEnd(apkfile, appinfo, PM_ERROR,
//                                        commandResult0.errorMsg, params);
//                            }
//                        }
//                        break;
                case INSTALL_LOCATION_INTERNAL_ONLY:
                    StringBuilder command1 = new StringBuilder().append("pm install -r ").append(
                            apkfile);
                    LogUtils.d("silent_install", "INSTALL_LOCATION_INTERNAL_ONLY silent install  cmd:" + command1);
                    ShellUtils.CommandResult commandResult1 = ShellUtils
                            .execCommand(command1.toString(), true, true);
                    if (commandResult1.successMsg != null
                            && (commandResult1.successMsg.contains("Success") || commandResult1.successMsg
                            .contains("success"))) {
//                        if (mInstallListener != null)
//                            mInstallListener.onInstallEnd(apkfile, appinfo, PM_SUCCESSS,
//                                    String.valueOf("Success"), params);
                        data.setData(0,appinfo,"");
//                        isInstallSuccess = true;
                        LogUtils.d("silent_install", "INSTALL_LOCATION_INTERNAL_ONLY Silent Install sucess..");
                        LogAPIForAppStore
                                .appStatusNew(-1, appinfo.pkgName, appinfo.appName, "安装成功", "");
                    } else {
//                        if (mInstallListener != null) {
                        LogUtils.d("silent_install", "INSTALL_LOCATION_INTERNAL_ONLY Silent Install failed  for:" + commandResult1.errorMsg);
//                            mInstallListener.onInstallEnd(apkfile, appinfo, PM_ERROR,
//                                    commandResult1.errorMsg, params);
//                        }
//                        isInstallSuccess = false;
                        data.setData(1,appinfo,commandResult1.errorMsg);
                    }
                    break;
                case INSTALL_LOCATION_PREFER_EXTERNAL:
                    if (SdCardChecker.isSDCardAvaiable()) {
                        String arg = " -s ";
                        if (needInstallSystem(apkfile)) {
//                            if (mInstallListener != null) {
                            LogUtils.d("silent_install", "INSTALL_LOCATION_PREFER_EXTERNAL Silent Install failed  for:  system apk  can not install to sdcard!");
//                                mInstallListener.onInstallEnd(apkfile, appinfo, PM_ERROR,
//                                        "systemuid", params);
//                            }
//                            isInstallSuccess = false;
                            data.setData(1,appinfo,"apk has systemuid,can not install sdcard!");
                            break;
                        }
                        StringBuilder command2 = new StringBuilder().append("pm install -r " + arg).append(
                                apkfile);
                        LogUtils.d("silent_install", "INSTALL_LOCATION_PREFER_EXTERNAL silent install  cmd:" + command2);
                        ShellUtils.CommandResult commandResult2 = ShellUtils
                                .execCommand(command2.toString(), true, true);
                        if (commandResult2.successMsg != null
                                && (commandResult2.successMsg.contains("Success") || commandResult2.successMsg
                                .contains("success"))) {
//                            if (mInstallListener != null)
//                                mInstallListener.onInstallEnd(apkfile, appinfo, PM_SUCCESSS,
//                                        String.valueOf("Success"), params);
//                            isInstallSuccess = true;
                            data.setData(0,appinfo,"");
                            LogUtils.d("silent_install", "INSTALL_LOCATION_PREFER_EXTERNAL Silent Install sucess..");
                            LogAPIForAppStore
                                    .appStatusNew(-1, appinfo.pkgName, appinfo.appName, "安装成功", "");
                        } else {
//                            if (mInstallListener != null) {
                            LogUtils.d("slient_install", "INSTALL_LOCATION_PREFER_EXTERNAL Silent Install failed  for:" + commandResult2.errorMsg);
//                                mInstallListener.onInstallEnd(apkfile, appinfo, PM_ERROR,
//                                        commandResult2.errorMsg, params);
//                            }
//                            isInstallSuccess = false;
                            data.setData(1,appinfo,commandResult2.errorMsg);
                        }
                    } else {
//                        if (mInstallListener != null) {
//                            try {
//                                Thread.sleep(1000);
//                            } catch (InterruptedException e) {
//                                e.printStackTrace();
//                            }
                        LogUtils.d("silent_install", "INSTALL_LOCATION_PREFER_EXTERNAL Silent Install failed...nosdcard..");
//                            mInstallListener.onInstallEnd(apkfile, appinfo, PM_ERROR,
//                                    "nosdcard", params);
//                        }
//                        isInstallSuccess = false;
                        data.setData(1,appinfo,"has no sdcard");
                    }
                    break;
                default:
                    break;
            }
        }
        return data;
    }

    private static InstallBackData unSilentInstallApp(String apkfile, boolean SP)
    {
        InstallBackData data = new InstallBackData();
        try {
            Runtime.getRuntime().exec("chmod 777 " + apkfile);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        AppInfo appinfo = getAPKInfo(apkfile);
        if (appinfo == null || appinfo.pkgName == null || appinfo.pkgName.equals("")) {
            LogUtils.d("install", "unSilentInstallApp  has no appInfo  " );
        }
        Uri uri = Uri.fromFile(new File(apkfile));
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (!SP)
            intent.putExtra("SKYWORTH_HIDE_FLAG_PACKAGENAME", CoocaaApplication.getContext().getPackageName());

        int preferlocation = getInstallLocation(apkfile);
        LogUtils.d("install", "preferlocation:" + preferlocation);
        switch (preferlocation) {
            case INSTALL_LOCATION_INTERNAL_ONLY:
                intent.putExtra("APP_INSTALL_LOCATION", 1);
                break;
            case INSTALL_LOCATION_PREFER_EXTERNAL:
            case INSTALL_LOCATION_AUTO:
            case INSTALL_LOCATION_UNSPECIFIED:
                if (SdCardChecker.isSDCardAvaiable()) {
                    intent.putExtra("APP_INSTALL_LOCATION", 2);
                } else {
                    intent.putExtra("APP_INSTALL_LOCATION", 0);
                }
                break;
        }
        CoocaaApplication.getContext().startActivity(intent);
        boolean installerExist = false;
        while(!installerExist)                             //第一次判断，需要出现installer
        {
            LogUtils.d("install", "wait installer  show!!");
            installerExist = isPackageInstallerExist();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        while(isPackageInstallerExist())                   //第二次判断，需要消失installer
        {
            LogUtils.d("install", "wait installer  dismiss!!");
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        boolean isInstalled = isAppInstalled(appinfo.pkgName);
        if(isInstalled) {
            data.setData(0, appinfo, "");
            return data;
        }
        else {
            data.setData(1, appinfo, "packageinstaller failed");
            return data;
        }
    }


    public static boolean unInstallAPP(String pkg, boolean silent){
        if(silent)
            return silentUnInstallApp(pkg);
        else
            return unSilentUnInstallApp(pkg);
    }

    private static boolean silentUnInstallApp(String pkgname){
//        AppInfo appInfo = getAppInfoFromLocal(pkgname);
//        mUnInstallListener.onUninstallStart(appInfo);
        boolean isUninstallAppSuccess = false;
        String command = "pm uninstall " + pkgname;
        try {
            Process process = Runtime.getRuntime().exec(command);
            process.waitFor();
            process.getOutputStream().toString();
            if (isAppInstalled(pkgname))
                isUninstallAppSuccess = false;
            else {
                isUninstallAppSuccess = true;
            }
            LogUtils.d("uninstall", "uninstall  isUninstallAppSuccess:"+isUninstallAppSuccess);
        } catch (Exception e) {
            e.printStackTrace();
            LogUtils.d("uninstall", "uninstall  error");
//            mUnInstallListener.onUninstallEnd(appInfo, PM_ERROR, e.toString());
        }
        return isUninstallAppSuccess;
    }

    private static boolean unSilentUnInstallApp(String pkgname){
        Uri packageURI = Uri.parse("package:" + pkgname);
        Intent intent = new Intent(Intent.ACTION_DELETE, packageURI);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        CoocaaApplication.getContext().startActivity(intent);
        LogUtils.d("uninstall", "unSilentUnInstallApp ");
        boolean installerExist = false;
        while(!installerExist)                             //第一次判断，需要出现installer
        {
            LogUtils.d("uninstall", "wait installer  show!!");
            installerExist = isPackageInstallerExist();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        while(isPackageInstallerExist())                   //第二次判断，需要消失installer
        {
            LogUtils.d("uninstall", "wait installer  dismiss!!");
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        boolean isInstalled = isAppInstalled(pkgname);
        if(isInstalled)
            return false;
        else
            return true;
    }


    public static AppInfo getAPKInfo(String apkfile) {
        try {
            AppInfo info = null;
            PackageInfo packageinfo = CoocaaApplication.getContext().getPackageManager().getPackageArchiveInfo(apkfile,
                    PackageManager.GET_ACTIVITIES);
            if (packageinfo != null) {
                info = new AppInfo();
                ApplicationInfo appInfo = packageinfo.applicationInfo;
                info.apkPath = apkfile;
                info.appName = "";
                try {
                    info.appName = CoocaaApplication.getContext().getPackageManager().getApplicationLabel(appInfo)
                            .toString();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                info.pkgName = appInfo.packageName;
                info.versionName = packageinfo.versionName;
                info.versionCode = packageinfo.versionCode;
            }
            return info;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private static int getConfigInstallLocation() {
        int ret = Settings.Secure.getInt(CoocaaApplication.getContext().getContentResolver(), "default_install_location", 0);
        LogUtils.d("install", "settings getInstallLocation:" + ret);
        return ret;
        // 0：自动
        // 1：内部
        // 2：外部
    }

    private static int getInstallLocation(String apk) {
        int pos = getConfigInstallLocation();
        LogUtils.d("install", apk + "settings getInstallLocation:" + pos);
        return pos;
    }

    private static boolean needInstallSystem(String apkPath) {
        PackageInfo pkgInfo = CoocaaApplication.getContext().getPackageManager().getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
        LogUtils.d("install", "(pkgInfo != null):" + (pkgInfo != null));
        if (pkgInfo != null) {
            if (pkgInfo.sharedUserId != null && pkgInfo.sharedUserId.equals("android.uid.system")) {
                LogUtils.d("install", apkPath + "is system uid !");
                return true;
            }
            boolean isSystemApp = isSystemApp(pkgInfo.packageName);
            if (isSystemApp)
                return true;
            return false;
        }
        return false;
    }

    private static boolean isSystemApp(String pkg) {
        PackageManager pm = CoocaaApplication.getContext().getPackageManager();
        try {
            ApplicationInfo info = pm.getApplicationInfo(pkg, PackageManager.GET_DISABLED_COMPONENTS);
            LogUtils.d("install", " sourceDir:" + info.sourceDir);
            if (info.sourceDir.startsWith("/system") || info.sourceDir.startsWith("system"))
                return true;
            return false;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }

    public static boolean isAppInstalled(String packageName) {
        PackageManager mPackageManager = CoocaaApplication.getContext().getPackageManager();
        PackageInfo info = null;
        try {
            info = mPackageManager.getPackageInfo(packageName, PackageManager.GET_DISABLED_COMPONENTS);
        } catch (PackageManager.NameNotFoundException e) {
            LogUtils.i("app", "isAppInstalled not installed!!  pkg:" + packageName + "  ");
            return false;
        }

        if (info != null)
            return true;
        else
            return false;
    }

    private static boolean isPackageInstallerExist() {
        ActivityManager manager = (ActivityManager) CoocaaApplication.getContext()
                .getSystemService(Context.ACTIVITY_SERVICE);

        List<ActivityManager.RunningTaskInfo> runningTaskInfos = manager.getRunningTasks(1);

        if (runningTaskInfos != null) {
            ComponentName cn = runningTaskInfos.get(0).topActivity;
            if (cn != null) {
                if (cn.getPackageName().contains("com.android.packageinstaller"))
                    return true;
            }
        }
        return false;
    }

}

